﻿using Cocon90.Lib.Dal.Tools;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;

namespace Cocon90.Lib.Dal.Store
{
    /// <summary>
    /// 一个基本具有分页、过滤等基本功能的数据集对象
    /// </summary>
    public class BaseStore<T> : IStore<T> where T : class,Rule.IModel, new()
    {
        public Type Model { get { return typeof(T); } }
        List<T> staticData = null;
        public List<T> StaticData
        {
            get
            {
                return staticData;
            }
            set
            {
                staticData = value;
            }
        }
        public List<T> Data { get; set; }

        int lastStaticPageNumber = 0;
        public virtual void Load(bool isNeedFilter = false)
        {
            var mh = new ModelHelper<T>();
            //只有当当前请求的页面不在StaticData所拥有的数据集的范围内时才再次访问数据库加载数据。
            if (lastStaticPageNumber != StaticPageNumber || isForceLoadStaticData)
            {
                isForceLoadStaticData = false;//立即关闭强行加载数据策略
                StaticData = mh.GetList(SelectSQLString);
                lastStaticPageNumber = StaticPageNumber;
            }
            Data = doFilter(PageNumber, PageSize, StaticData, isNeedFilter);
            if (OnDataChanged != null)
                OnDataChanged(Data, StaticData, PageNumber, PageSize, StaticPageNumber, StaticPageSize);
        }
        private bool isForceLoadStaticData = false;
        public void ForceLoadStaticDataOneTime()
        {
            //启动强行加载数据策略
            isForceLoadStaticData = true;
        }
        public virtual void LoadFrom(System.Data.DataTable dataTable, bool isNeedFilter = false)
        {
            if (dataTable == null) return;
            var mh = new ModelHelper<T>();
            if (lastStaticPageNumber != StaticPageNumber || isForceLoadStaticData)
            {
                isForceLoadStaticData = false;//立即关闭强行加载数据策略
                StaticData = mh.GetList(doTablePaged(dataTable, StaticPageNumber, StaticPageSize));
                lastStaticPageNumber = StaticPageNumber;
            }
            Data = doFilter(PageNumber, PageSize, StaticData, isNeedFilter);
            if (OnDataChanged != null)
                OnDataChanged(Data, StaticData, PageNumber, PageSize, StaticPageNumber, StaticPageSize);
        }
        private List<T> doFilter(int currentPage, int pageSize, List<T> StaticData, bool isNeedFilter)
        {
            List<T> data = new List<T>();
            if (StaticData.Count < StaticPageSize)
            {//若是少量数据

                int indexStart = 0;
                int indexEnd = 0;
                int page = (currentPage - 1) % PageCountOneTimeLoad;
                indexStart = page * pageSize;
                if (StaticData.Count <= indexStart + pageSize)
                { indexEnd = StaticData.Count; }
                else
                { indexEnd = indexStart + pageSize; }
                for (int i = indexStart; i < indexEnd; i++)
                {
                    if (isNeedFilter)
                    {
                        foreach (var prop in Model.GetProperties())
                        {
                            if (Filter(i, prop.Name, prop.GetValue(StaticData[i], null)))
                                data.Add(StaticData[i]);
                        }
                    }
                    else
                    {
                        data.Add(StaticData[i]);
                    }
                }
            }
            else
            {//若是大量数据
                for (int i = (currentPage - 1) * pageSize; i < PageSize + ((currentPage - 1) * pageSize); i++)
                {
                    if (isNeedFilter)
                    {
                        foreach (var prop in Model.GetProperties())
                        {
                            if (Filter(i % StaticPageSize, prop.Name, prop.GetValue(StaticData[i % StaticPageSize], null)))
                                data.Add(StaticData[i % StaticPageSize]);
                        }
                    }
                    else
                    {
                        data.Add(StaticData[i % StaticPageSize]);
                    }
                }
            }
            return data;
        }
        private DataTable doTablePaged(DataTable dt, int staticPageNumber, int staticPageSize)
        {
            if (dt == null) return null;
            DataTable newdt = dt.Clone();
            for (int i = (staticPageNumber - 1) * staticPageSize; i < staticPageNumber * staticPageSize; i++)
            {
                newdt.ImportRow(dt.Rows[i]);
            }
            return newdt;
        }
        string selectSqlString = String.Format("select * from {0}", ((T)Activator.CreateInstance(typeof(T))).TableName);

        public string OldSelectSQLString { get { return selectSqlString; } }
        public string SelectSQLString
        {
            get
            {
                var db = DataHelperFactory.CreateInstence();
                var obj = (T)Activator.CreateInstance(Model);
                var primeryKey = db.getString(sqlHelper.getPrimeryKey(obj.TableName));
                return sqlHelper.getPagedSql(selectSqlString, primeryKey, IsAsc, StaticPageNumber, StaticPageSize);
            }
            set
            {
                selectSqlString = value;
            }
        }
        int pageSize = 20;
        public int PageSize
        {
            get
            {
                return pageSize;
            }
            set
            {
                pageSize = value;
            }
        }

        /// <summary>
        /// 是否是升序排列记录
        /// </summary>
        public bool IsAsc { get; set; }

        int pageNumber = 1;
        public int PageNumber
        {
            get
            {
                return pageNumber;
            }
            set
            {
                if (value >= 1)
                    pageNumber = value;
                else
                    pageNumber = 1;
            }
        }

        int pageCountOneTimeLoad = 3;
        public int PageCountOneTimeLoad
        {
            get
            {
                return pageCountOneTimeLoad;
            }
            set
            {
                pageCountOneTimeLoad = value;
            }
        }
        /// <summary>
        ///获取 缓冲数据集的次取的记录数。
        /// </summary>
        public int StaticPageSize { get { return PageSize * PageCountOneTimeLoad; } }
        /// <summary>
        ///获取 缓冲数据集当前取第几页的数据。
        /// </summary>
        public int StaticPageNumber { get { return 1 + ((PageNumber - 1) / PageCountOneTimeLoad); } }
        bool Filter(int index, string properties, object value)
        {
            if (FilterFunction != null)
            {
                return FilterFunction(index, properties, value);
            }
            return true;
        }

        public int GetAllRowCount()
        {
            var sql = String.Format("select count(*) from ({0}) tempCountTable", selectSqlString);
            var db = DataHelperFactory.CreateInstence();
            return db.getNumber(sql);
        }
        public event DataChanged OnDataChanged;
        public event FilterDelegate FilterFunction;




    }
}
